package com.terry.proxy.util;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.extern.java.Log;

import java.util.function.BiConsumer;
import java.util.function.Consumer;

/**
 * tcp回调
 *
 * @author allen
 * @date 2022/12/09
 */
@Log
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class TcpConsumer<T> {

    // 连接成功的回调
    private Consumer<ChannelHandlerContext> channelActive;

    // 收到数据回调
    private BiConsumer<ChannelHandlerContext, T> channelRead0;

    // 断开连接的回调
    private Consumer<ChannelHandlerContext> channelInactive;

    // 出现错误的回调
    private BiConsumer<ChannelHandlerContext, Throwable> exceptionCaught;

    public Consumer<ChannelPipeline> toPipeline(){
        return channelPipeline -> channelPipeline.addLast(builderCallback());
    }

    public Consumer<Bootstrap> toBootstrap(){
        return bootstrap -> bootstrap.handler(builderCallback());
    }

    public SimpleChannelInboundHandler<T> builderCallback(){
        return new SimpleChannelInboundHandler<T>() {

            /**
             * 建立连接的回调
             */
            @Override
            public void channelActive(ChannelHandlerContext ctx) throws Exception {
                if (channelActive != null) {
                    channelActive.accept(ctx);
                }
                super.channelActive(ctx);
            }

            /**
             * 接收到消息的回调
             * @param channelHandlerContext 消息
             * @param msg 消息
             */
            @Override
            protected void channelRead0(ChannelHandlerContext channelHandlerContext, T msg) throws Exception {
                if (channelRead0 != null) {
                    channelRead0.accept(channelHandlerContext, msg);
                }
            }


            /**
             * 断开连接的回调
             */
            @Override
            public void channelInactive(ChannelHandlerContext ctx) {
                try {
                    if (channelInactive != null) {
                        channelInactive.accept(ctx);
                    }
                    super.channelInactive(ctx);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
                super.userEventTriggered(ctx, evt);
            }

            @Override
            public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
                super.channelWritabilityChanged(ctx);
            }

            /**
             * 出现错误的回调
             * @param cause 导致
             */
            @Override
            public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
                if (exceptionCaught != null) {
                    exceptionCaught.accept(ctx, cause);
                }
                super.exceptionCaught(ctx, cause);
            }
        };
    }
}
